<template>
  <div class="connect">
    <div class="chat-layout" v-if="showChat">
      <div class="chat-head">
        <div class="online-service">{{ $t("onlineService") }}</div>
        <i class="el-icon-arrow-down arrow-down" @click="handleConnect"></i>
      </div>
      <div class="chat-content" id="chatContent">
        <div class="message-item-tip">{{ $t("noMoreMessage") }}</div>
        <div v-for="msg in msgReceive" :key="msg.id" :class="[msg.isSelf ? 'my-msg-wrap' : 'other-msg-wrap']">
          <!-- <div class="msg-divider">
            <div class="time-divider">
              <div class="divider-text">
                <span class="time-text">{{ msg.time }}</span>
              </div>
            </div>
          </div> -->
          <div class="msg-time">{{ msg.time }}</div>
          <div :class="[msg.isSelf ? 'my-msg' : 'other-msg']">{{ msg.content }}</div>
          <!-- <div>消息id-{{ msg.id }}***房间id-{{ msg.roomId }}***用户id-{{ msg.cid }}</div> -->
        </div>
      </div>
      <div class="chat-textarea">
        <el-input type="textarea" v-model="boxMsg" :placeholder="$t('writeMassage')"></el-input>
        <el-button class="send-btn" icon="el-icon-s-promotion" :disabled="!boxMsg" circle @click="handleSend"></el-button>
      </div>
    </div>
    <div class="side-connect" @click="handleConnect">
      <el-button class="side-btn" type="primary" icon="el-icon-error" circle v-if="showChat"></el-button>
      <el-button class="side-btn" type="primary" icon="el-icon-s-comment" circle v-else></el-button>
    </div>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      showChat: false, //是否显示聊天界面
      websock: null, //建立的连接
      lockReconnect: false, //是否真正建立连接
      timeout: 20 * 1000, //20秒一次心跳
      timeoutObj: null, //心跳心跳倒计时
      timeOutNum: null, //断开重连倒计时
      msgReceive: [], //显示的值
      boxMsg: "", //输入框的值
      pingMsg: { type: 1, desc: "ping" } //定时向服务器
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  beforeDestroy() {
    this.closeWebsocket()
  },
  methods: {
    handleConnect() {
      this.showChat = !this.showChat
      if (this.showChat) {
        this.$push.Permission.request(
          () => {
            console.log("桌面推送授权成功")
          },
          () => {
            console.log("桌面推送未授权")
          }
        )
        this.initWebSocket()
        this.listHistory()
      } else {
        this.closeWebsocket()
      }
    },
    async handleSend() {
      if (!this.boxMsg || this.boxMsg.trim().length == 0) return
      const param = { webUniqueId: this.getClientId(), content: this.boxMsg.trim() }
      let result = await this.$api.sendMsgUrl({ ...param })
      if (result.code == 0) {
        this.boxMsg = "" //消息发送成功清除输入框的值
        this.listHistory() //消息发送成功查询会话列表
      } else {
        console.log("消息发送失败", result.msg)
      }
    },
    async listHistory() {
      const param = { webUniqueId: this.getClientId() }
      let response = await this.$api.listMsgUrl({ ...param })
      if (response?.code == 0) {
        this.msgReceive.length = 0
        if (response?.data) {
          response.data.forEach((item) => this.msgReceive.push(item))
          setTimeout(() => {
            this.scrollToBottom()
          }, 500)
        }
      }
    },
    getClientId() {
      var key = "Client-Id"
      var webUniqueId = this.$cookies.get(key)
      if (webUniqueId) {
        return webUniqueId
      }
      webUniqueId = this.uuid()
      this.$cookies.set(key, webUniqueId)
      return webUniqueId
    },
    scrollToBottom() {
      var myDiv = document.getElementById("chatContent")
      let h = myDiv.scrollHeight - myDiv.clientHeight
      myDiv.scrollTop = h
      console.log("msg=scrollToBottom", h)
    },
    uuid() {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
        var r = (Math.random() * 16) | 0,
          v = c == "x" ? r : (r & 0x3) | 0x8
        return v.toString(16)
      })
    },
    initWebSocket() {
      //后台地址，前面的ws不动，后面是后台地址，我是本地运行的所以填的本地，自行更改。再后面webSocket是后端的接口地址，uuid_test002是参数4
      //const wsuri = "ws://oapi-yunliantest.sany.com.cn/mp/talk-service/web-socket";
      const wsuri = `${this.$api.webSocketUrl}/${this.getClientId()}`
      //建立连接
      this.websock = new WebSocket(wsuri)
      //连接成功
      this.websock.onopen = this.websocketOnOpen
      //连接错误
      this.websock.onerror = this.websocketOnError
      //接收信息
      this.websock.onmessage = this.websocketOnMessage
      //连接关闭
      this.websock.onclose = this.websocketClose
    },
    reconnect() {
      if (this.lockReconnect) return
      this.lockReconnect = true
      this.timeOutNum && clearTimeout(this.timeOutNum)
      this.timeOutNum = setTimeout(() => {
        this.initWebSocket()
        this.lockReconnect = false
      }, 5000)
    },
    reset() {
      clearTimeout(this.timeoutObj)
      this.start()
    },
    start() {
      this.timeoutObj && clearTimeout(this.timeoutObj)
      this.timeoutObj = setTimeout(() => {
        if (this.websock.readyState == 1) {
          this.websock.send(JSON.stringify(this.pingMsg))
        } else {
          this.reconnect()
        }
      }, this.timeout)
    },
    websocketOnOpen() {
      this.websocketSend(JSON.stringify(this.pingMsg))
      console.log("连接成功")
      this.start()
    },
    websocketOnError(e) {
      console.log("WebSocket连接发生错误")
      this.reconnect()
    },
    websocketClose(e) {
      if (!this.websock) return
      this.websock.close()
      console.log("连接已自动关闭")
      this.reconnect()
    },
    closeWebsocket() {
      if (!this.websock) return
      this.websock.close()
      this.websock = null
      console.log("连接已手动关闭")
    },
    websocketOnMessage(event) {
      console.log("收到服务器信息", event.data)
      let card = JSON.parse(event.data)
      if (card?.type == 2) {
        this.listHistory()
        this.notify(card.desc)
      }
    },
    websocketSend(msg) {
      this.websock.send(msg)
    },
    notify(message) {
      let canPush = this.$push.Permission.has()
      console.log(`新通知 canPush:${canPush} - msg-${message}`)
      if (message && canPush) {
        this.$push.create(this.$i18n.t("newMessage"), {
          body: message,
          requireInteraction: true, // 是否显示关闭、设置按钮
          icon: "https://yunlian-oss-product.oss-cn-hangzhou.aliyuncs.com/website/msg-logo.png", // 右侧图标，也可以是png url
          timeout: 8000 // 显示时间
        })
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.connect {
  position: fixed;
  bottom: 30px;
  right: 20px;
  z-index: 999;
  .chat-layout {
    width: 300px;
    height: 400px;
    background: #fff;
    box-shadow: 0 2px 7px 0 rgba(0, 0, 0, 0.14);
    border-radius: 8px;
    overflow: hidden;
    .chat-head {
      width: 100%;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      background: #0064ff;
      padding: 0 10px;
      box-sizing: border-box;
      .online-service {
        font-size: 12px;
        color: #fff;
      }
      .arrow-down {
        font-size: 14px;
        color: #fff;
        cursor: pointer;
      }
    }
    .chat-content {
      width: 100%;
      height: 330px;
      padding: 15px;
      box-sizing: border-box;
      overflow-y: auto;
      &::-webkit-scrollbar {
        display: none;
      }
      .message-item-tip {
        font-size: 12px;
        text-align: center;
        color: rgba(140, 140, 140);
      }
      .my-msg-wrap {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: end;
        margin-bottom: 10px;
        .my-msg {
          max-width: 70%;
          color: #2a2a2a;
          font-size: 12px;
          font-weight: 400;
          background-color: #ddefff;
          border-radius: 6px;
          line-height: 20px;
          padding: 4px 8px;
        }
      }
      .other-msg-wrap {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: start;
        margin-bottom: 10px;
        .other-msg {
          max-width: 70%;
          color: #2a2a2a;
          font-size: 12px;
          font-weight: 400;
          background: #eee;
          border-radius: 6px;
          line-height: 20px;
          padding: 4px 8px;
        }
      }
      .msg-divider {
        width: 75%;
        padding: 5px;
        margin: 0 auto;
        .time-divider {
          width: 100%;
          min-width: 100%;
          border-top-color: rgba(0, 0, 0, 0.06);
          color: rgba(0, 0, 0, 0.85);
          white-space: nowrap;
          clear: both;
          display: flex;
          margin: 10px 0;
          .divider-text {
            display: inline-block;
            padding: 0 5px;
            .time-text {
              font-size: 12px;
              color: #909090;
            }
          }
        }
        .time-divider:after,
        .time-divider:before {
          border-bottom: 0;
          border-top: 1px solid transparent;
          border-top-color: inherit;
          content: "";
          position: relative;
          top: 50%;
          transform: translateY(50%);
          width: 50%;
        }
      }
      .msg-time {
        font-size: 12px;
        color: #909090;
        line-height: 22px;
      }
    }
    .chat-textarea {
      width: 100%;
      height: 40px;
      border-top: 1px solid #e6e6e6;
      position: relative;
      ::v-deep .el-textarea__inner {
        width: 100%;
        height: 40px;
        min-height: 40px;
        max-height: 40px;
        line-height: 20px;
        border: none;
        resize: none;
        padding: 3px 30px 3px 8px;
        &::placeholder {
          font-size: 12px;
        }
        &::-webkit-scrollbar {
          display: none;
        }
      }
      .send-btn {
        font-size: 18px;
        color: #8a8a8a;
        position: absolute;
        top: 6px;
        right: 2px;
        padding: 4px;
        border: none;
        &:hover {
          color: #0064ff;
        }
      }
    }
  }
  .side-connect {
    text-align: right;
    margin-top: 15px;
    cursor: pointer;
    .side-btn {
      width: 50px;
      height: 50px;
      background: #0064ff;
      border-color: #0064ff;
      ::v-deep .el-icon-s-comment {
        font-size: 20px;
      }
      ::v-deep .el-icon-error {
        font-size: 20px;
        animation: rotate 2s 1;
      }
    }
    &:hover .side-btn {
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
    }
    @keyframes rotate {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
  }
}
</style>
